package com.dx.mes.service.special.service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.dx.common.table.ppt.Bis_ope;
import com.dx.common.table.ppt.Bis_opeId;
import com.dx.common.table.ppt.Bis_pathi;
import com.dx.common.table.ppt.Bis_pathiId;
import com.dx.common.table.ppt.Ret_prd_info;
import com.dx.mes.common.dao.IBisOpeDao;
import com.dx.mes.common.dao.IBisPathDao;
import com.dx.mes.common.dao.IBisPathiDao;
import com.dx.mes.common.dao.IRetBoxDao;
import com.dx.mes.common.dao.IRetPrdInfoDao;
import com.dx.mes.common.transcoder.util.AppContext;
import com.dx.mes.common.transcoder.util.JacksonUtil;
import com.dx.mes.common.transcoder.util.LogUtils;
import com.dx.mes.common.transcoder.util.Util;
import com.dx.mes.facade.special.service.IFspskipopeService;
import com.dx.mes.facade.special.tx.Fspskipope.FspskipopeI;
import com.dx.mes.facade.special.tx.Fspskipope.FspskipopeIA;
import com.dx.mes.facade.special.tx.Fspskipope.FspskipopeO;

import static com.dx.mes.common.bean.def.GenericDef.*;
import static com.dx.mes.common.bean.def.GenericDef.E_FPPMOVEIN_TOOL_WO_NOT;

@Service("fspskipopeService")
@SuppressWarnings({"unchecked"})
public class FspskipopeService implements IFspskipopeService{
	private LogUtils logUtils;
	private static String TX_NAME =  T_FSPSKIPOPE;
	
	@Autowired
	private IRetBoxDao retBoxDao;
	@Autowired
	private IRetPrdInfoDao retPrdInfoDao;
	@Autowired
	private IBisOpeDao bisOpeDao;
	@Autowired
	private IBisPathDao bisPathDao;
	@Autowired
	private IBisPathiDao bisPathiDao;

	@Override
	public String subMainProc(String evt_no, String strInMsg) {
		AppContext.clear();
		AppContext.setCurrServiceName(FspskipopeService.class.getSimpleName());
		AppContext.setCurrEventNumber(evt_no);
		logUtils = new LogUtils(FspskipopeService.class);
		logUtils.info("[InTrx:" + strInMsg + "]");
		
		Session session = retPrdInfoDao.getCrSession();
		long rtnCode = _NORMAL;
		String outMsg = "";

		FspskipopeI inTrx = new FspskipopeI();
		FspskipopeO outTrx = new FspskipopeO();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));
		outTrx.setType_id(TRX_OUT);
	
		try {
			inTrx = JacksonUtil.fromJson(strInMsg, FspskipopeI.class);

			rtnCode = subMainProc2(inTrx, outTrx);
			if (rtnCode != _NORMAL) {
				TransactionAspectSupport.currentTransactionStatus()
						.setRollbackOnly();
				outTrx.setRtn_code(String.valueOf(rtnCode));
			} else {
				session.flush();
			}
		} catch (Exception ex) {
			TransactionAspectSupport.currentTransactionStatus()
					.setRollbackOnly();
			outTrx.setRtn_mesg(ex.toString());
			outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
			logUtils.error(Util.stackTraceToString(ex));
		} finally {
			outMsg = JacksonUtil.toJSONStr(outTrx);
			logUtils.info("[OutTrx:" + outMsg + "]");
		}
		return outMsg;
	}

	private long subMainProc2(FspskipopeI inTrx, FspskipopeO outTrx) {
		char actionType = inTrx.getAction_flg().toCharArray()[0];
		long lRc = _NORMAL;
		switch (actionType) {
		case 'J':
			lRc = jumpOpe(inTrx,outTrx);
			if (lRc != _NORMAL) {
				return lRc;
			}
			break;

		default:
			break;
		}
		return lRc;
	}

	private long jumpOpe(FspskipopeI inTrx, FspskipopeO outTrx) {
		long lRc = _NORMAL;
		Timestamp current_timestamp = Util.getCurrentTimestamp();
		List<FspskipopeIA> iary = inTrx.getIary();
		Bis_pathiId pathiId = new Bis_pathiId(inTrx.getNx_path_id_fk(),inTrx.getNx_path_ver_fk());
		Bis_pathi bis_pathi = bisPathiDao.get(pathiId);
		if(bis_pathi == null){
			outTrx.setRtn_mesg("工艺路线[" + inTrx.getNx_path_id_fk() 
					+ "][" + inTrx.getNx_path_ver_fk() + "]未设定");
			return E_BIS_PATHI + E_READ_NOT_FOUND;
		}
		
		Bis_opeId bis_opeId = new Bis_opeId();
		bis_opeId.setOpe_id(inTrx.getNx_ope_id_fk());
		bis_opeId.setOpe_ver(inTrx.getNx_ope_ver_fk());
		Bis_ope bis_ope = bisOpeDao.get(bis_opeId);
		if (null == bis_ope) {
			outTrx.setRtn_mesg("站点[" + inTrx.getNx_ope_id_fk() 
					+ "][" + inTrx.getNx_ope_ver_fk() + "]未设定");
			return E_BIS_OPE + E_READ_NOT_FOUND;
		}
		List<Ret_prd_info>  ret_prd_infos = new ArrayList<Ret_prd_info>();
		for(int i=0; i<iary.size(); i++){
			Ret_prd_info ret_prd_info = retPrdInfoDao.get(iary.get(i).getPrd_seq_id());
			if(ret_prd_info == null){
				outTrx.setRtn_mesg("玻璃代码[" + iary.get(i).getPrd_seq_id() + "]不存在！");
				return E_RET_BOX + E_READ_NOT_FOUND;
			}
			if("REWFMA01".equals(ret_prd_info.getNx_path_id_fk())){
				outTrx.setRtn_mesg("屏体代码[" + iary.get(i).getPrd_seq_id() + "]在FMA站点，无法跳站");
				return E_FSPSKIPOPE_INVALID_STATUS;
			}
			if( _NG.equals(ret_prd_info.getExt_9())){
				outTrx.setRtn_mesg("屏体代码[" + iary.get(i).getPrd_seq_id() + "]属于NG品，无法跳站");
				return E_FSPSKIPOPE_INVALID_STATUS;
			}
			if (BANK_IN.equals(ret_prd_info.getBnk_flg())) {
				outTrx.setRtn_mesg("屏体代码[" + iary.get(i).getPrd_seq_id() + "]在在制仓内，无法跳站");
				return E_FSPSKIPOPE_INVALID_STATUS;
			}
			if(!PROC_WAIT.equals(ret_prd_info.getPrd_stat())){
				outTrx.setRtn_mesg("玻璃代码[" + iary.get(i).getPrd_seq_id() 
						+ "]状态为[" + ret_prd_info.getPrd_stat() 
						+ "],必须为[" + PROC_WAIT + "],不能跳站！");
				return E_FSPSKIPOPE_INVALID_STATUS;
			}
			ret_prd_info.setNx_path_id_fk(inTrx.getNx_path_id_fk());
			ret_prd_info.setNx_path_ver_fk(inTrx.getNx_path_ver_fk());
			ret_prd_info.setNx_ope_no_fk(inTrx.getNx_ope_no_fk());
			ret_prd_info.setNx_ope_id_fk(inTrx.getNx_ope_id_fk());
			ret_prd_info.setNx_ope_ver_fk(inTrx.getNx_ope_ver_fk());
			ret_prd_info.setNx_proc_id_fk(bis_ope.getProc_id());
			ret_prd_info.setNx_tool_run_mode(bis_ope.getTool_run_mode());
			ret_prd_info.setNx_toolg_id_fk(bis_ope.getToolg_id_fk());
			ret_prd_info.setEvt_cate(EVT_SKIP_OPERATION);
			ret_prd_info.setEvt_usr(inTrx.getEvt_usr());
			ret_prd_info.setEvt_timestamp(current_timestamp);
			ret_prd_infos.add(ret_prd_info);
		}
		retPrdInfoDao.saveOrUpdateAll(ret_prd_infos);
		outTrx.setRtn_code(RETURN_CODE_OK);
		outTrx.setRtn_mesg(RETURN_MESG_OK);
		return lRc;
	}

}
